//
//  ChatViewController.m
//  MyChatDemo
//
//  Created by DragonYao on 2017/9/11.
//  Copyright © 2017年 DragonYao. All rights reserved.
//

#import "ChatViewController.h"
#import "SLInputView.h"
#import "UIImageView+WebCache.h"
#import "HttpTool.h"
#import "SLChatTextCell.h"
#import "SLChatImageCell.h"
#import "SLChatAudioCell.h"
#import "SLChatFileCell.h"
#import "SLChatVideoCell.h"

static NSString *kTextCellId = @"SLChatTextCell";
static NSString *kImageCellId = @"SLChatImageCell";
static NSString *kAudioCellId = @"SLChatAudioCell";
static NSString *kFileCellId = @"SLChatFileCell";
static NSString *kVideoCellId = @"SLChatVideoCell";

static NSString *kBodyTypeKey = @"bodyType";
static NSString *kImgRatioKey = @"imageRatio";
static NSString *kVideoKey = @"videoKey";

@interface ChatViewController ()<UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate, UITextViewDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate> {
    NSFetchedResultsController *_fetchVC;
}

@property (nonatomic, strong) NSLayoutConstraint *inputBottomConstraint;
@property (nonatomic, strong) NSLayoutConstraint *inputViewHeightConstraint;
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) HttpTool *httpTool;

@end

@implementation ChatViewController

- (void)dealloc {
    SLog(@"%@ dealloc ", self);
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    if (self.tableView.contentSize.height > kWIDTH) {
        [self scrollTableToBottom];
    }
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupViews];//创建Views
    [self fetchMessageData];
    [self setupNavigationBarItems];
    //监听键盘
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardChangedFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
}

- (void)fetchMessageData {
    //获取上下文
    NSManagedObjectContext *context = [XMPPManager sharedManager].msgStorage.mainThreadManagedObjectContext;
    //请求对象
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"XMPPMessageArchiving_Message_CoreDataObject"];
    //过滤条件 (当前用户的JID 和 好友的JID)
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"streamBareJidStr = %@ AND bareJidStr = %@", [UserLocalInfo sharedUserInfo].myJid, self.friendJID.bare];
    request.predicate = pre;
    //按时间升序排列
    NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"timestamp" ascending:YES];
    request.sortDescriptors = @[sort];
    NSError *error = nil;
    _fetchVC = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];
    _fetchVC.delegate = self;
    [_fetchVC performFetch:&error];
    
    if (error) {
        SLog(@"chat result message error = %@", error);
    }
}

- (void)setupViews {
    //创建view
    UITableView *tableView = [[UITableView alloc] init];
    tableView.translatesAutoresizingMaskIntoConstraints = NO;
    tableView.delegate = self;
    tableView.dataSource = self;
    tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    [self.view addSubview:tableView];
    tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
    self.tableView = tableView;
    
    //register cell
    [tableView registerClass:[SLChatTextCell class] forCellReuseIdentifier:kTextCellId];
    [tableView registerClass:[SLChatImageCell class] forCellReuseIdentifier:kImageCellId];
    [tableView registerClass:[SLChatAudioCell class] forCellReuseIdentifier:kAudioCellId];
    [tableView registerClass:[SLChatFileCell class] forCellReuseIdentifier:kFileCellId];
    [tableView registerClass:[SLChatVideoCell class] forCellReuseIdentifier:kVideoCellId];
    
    SLInputView *inputView = [SLInputView inputView];
    inputView.translatesAutoresizingMaskIntoConstraints = NO;
    inputView.textView.delegate = self;
    inputView.textView.returnKeyType = UIReturnKeySend;
    [self.view addSubview:inputView];
    [inputView.photoBtn addTarget:self action:@selector(showImagePickVC:) forControlEvents:UIControlEventTouchUpInside];
    //水平布局
    NSDictionary *viewsDict = @{@"tableView":tableView,
                                @"inputView":inputView};
    NSArray<NSLayoutConstraint *> *tableConstraintH = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[tableView]-0-|" options:0 metrics:nil views:viewsDict];//tableView水平方向的约束
    [self.view addConstraints:tableConstraintH];
    NSArray<NSLayoutConstraint *> *inputConstraintH = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[inputView]-0-|" options:0 metrics:nil views:viewsDict];
    [self.view addConstraints:inputConstraintH];
    //垂直方向
    NSArray<NSLayoutConstraint *> *viewsConstraintV = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[tableView]-0-[inputView(50)]-0-|" options:0 metrics:nil views:viewsDict];
    [self.view addConstraints:viewsConstraintV];
    self.inputBottomConstraint = [viewsConstraintV lastObject];
    if (viewsConstraintV.count > 2) {
        self.inputViewHeightConstraint = [viewsConstraintV objectAtIndex:2];
    }
//    SLog(@"%@", viewsConstraintV);
}

- (void)setupNavigationBarItems {
    UIBarButtonItem *meItem = [[UIBarButtonItem alloc] initWithTitle:@"我" style:(UIBarButtonItemStylePlain) target:self action:@selector(mySendImage:)];
    UIBarButtonItem *friendItem = [[UIBarButtonItem alloc] initWithTitle:@"好友" style:(UIBarButtonItemStylePlain) target:self action:@selector(friendSendImage:)];
    self.navigationItem.rightBarButtonItems = @[meItem,friendItem];
}

- (void)mySendImage:(id)sender {
    NSDictionary *imgInfo = [self getImgPathWithRandom:arc4random_uniform(5)];
    
    [self sendMsgWithText:[imgInfo valueForKey:@"imagePath"] bodyType:@"image" imageRatio:[[imgInfo valueForKey:kImgRatioKey] floatValue]];
}

- (void)friendSendImage:(id)sender {
    NSString *videoUrl = [self getVideoURLString:arc4random_uniform(2)];
    [self sendMsgWithText:videoUrl bodyType:@"video" imageRatio:0];
}

#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _fetchVC.fetchedObjects.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    SLChatTextCell *textCell = [tableView dequeueReusableCellWithIdentifier:kTextCellId];
    if (textCell == nil) {
        textCell = [[SLChatTextCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:kTextCellId];
    }
    SLChatImageCell *imgCell = [tableView dequeueReusableCellWithIdentifier:kImageCellId];
    if (imgCell == nil) {
        imgCell = [[SLChatImageCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:kImageCellId];
    }
    SLChatAudioCell *audioCell = [tableView dequeueReusableCellWithIdentifier:kAudioCellId];
    if (audioCell == nil) {
        audioCell = [[SLChatAudioCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:kAudioCellId];
    }
    SLChatFileCell *fileCell = [tableView dequeueReusableCellWithIdentifier:kFileCellId];
    if (fileCell == nil) {
        fileCell = [[SLChatFileCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:kFileCellId];
    }
    SLChatVideoCell *videoCell = [tableView dequeueReusableCellWithIdentifier:kVideoCellId];
    if (videoCell == nil) {
        videoCell = [[SLChatVideoCell alloc] initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:kVideoCellId];
    }
    XMPPMessageArchiving_Message_CoreDataObject *msg = _fetchVC.fetchedObjects[indexPath.row];
    NSString *bodyType = [msg.message attributeStringValueForName:kBodyTypeKey];
    
    if ([bodyType isEqualToString:@"text"]) {//文本
        if ([msg.outgoing boolValue]) {//自己发出去的消息
            [textCell layoutFrameWithText:msg.body withNickname:@"我的昵称" fromFriends:NO];
        }
        else {
            [textCell layoutFrameWithText:msg.body withNickname:@"Friends昵称" fromFriends:YES];
        }
        return textCell;
    }
    else if ([bodyType isEqualToString:@"image"]) {//图片
        
        imgCell.indexRow = indexPath.row;
        if ([msg.outgoing boolValue]) {
            [imgCell configCellWithImgPath:msg.body isFriends:NO];
        }
        else {
            [imgCell configCellWithImgPath:msg.body isFriends:YES];
        }
        return imgCell;
    }
    else if ([bodyType isEqualToString:@"audio"]) {//音频
        return audioCell;
    }
    else if ([bodyType isEqualToString:@"video"]) {
        
        return videoCell;
    }
    else {
        [textCell layoutFrameWithText:msg.body withNickname:@"Friends昵称" fromFriends:YES];
        return textCell;
    }
}

#pragma mark - UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    XMPPMessageArchiving_Message_CoreDataObject *msg = _fetchVC.fetchedObjects[indexPath.row];
    NSString *bodyType = [msg.message attributeStringValueForName:kBodyTypeKey];
    if ([bodyType isEqualToString:@"text"]) {
        return [SLChatTextCell cellHeight:msg];
    }
    else if ([bodyType isEqualToString:@"image"]) {
        CGFloat imgRatio = [msg.message attributeFloatValueForName:kImgRatioKey];
        SLog(@"imageRatio = %f", imgRatio);
        return [SLChatImageCell cellHeightWithImageRatio:imgRatio];
    }
    else if ([bodyType isEqualToString:@"audio"]) {
        return CGFLOAT_MIN;
    }
    else if ([bodyType isEqualToString:@"video"]) {
        return CGFLOAT_MIN;
    }
    else {
        return [SLChatTextCell cellHeight:msg];
    }
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    
}

#pragma mark - NSFetchedResultsControllerDelegate
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    SLog(@"数据发生改变");
    [self.tableView reloadData];
    [self scrollTableToBottom];
}

- (void)keyboardChangedFrame:(NSNotification *)notification {
    //键盘结束的frame
    CGRect frame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    //键盘结束的Y值
    CGFloat offsetY = frame.origin.y;
    self.inputBottomConstraint.constant = (kHEIGHT - offsetY);
    [self scrollTableToBottom];
}

- (void)showImagePickVC:(id)sender {
    //调出图片选择器
    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
    imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    imagePicker.delegate = self;
    [self presentViewController:imagePicker animated:YES completion:nil];
}

- (void)scrollTableToBottom {
    if (_fetchVC.fetchedObjects.count == 0) { return; }
    NSIndexPath *lastIndexPath = [NSIndexPath indexPathForRow:_fetchVC.fetchedObjects.count - 1 inSection:0];
    [self.tableView scrollToRowAtIndexPath:lastIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}

//监听点击发送
- (void)textViewDidChange:(UITextView *)textView {
    CGFloat textViewH = textView.contentSize.height;
    if (textViewH > 33.0 && textViewH < 67.0) {
        self.inputViewHeightConstraint.constant = textViewH + 20.0;
    }
}


/**
 * 判断输入的字是否是回车，即按下return 在这里做你响应return键的代码
 * 这里返回NO，就代表return键值失效，即页面上按下return，不会出现换行，
 * 如果为yes，则输入页面会换行
 */
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    
    if ([text isEqualToString:@"\n"]){
        NSMutableString *text = [NSMutableString stringWithString:textView.text];
        if ([SLUtils isNilString:text]) { return NO; }
        //发送
        [self sendMsgWithText:text bodyType:@"text" imageRatio:0];
        textView.text = @"";
        self.inputViewHeightConstraint.constant = 50.0;
        return NO;
    }
    return YES;
}


//发送消息（文本 text， 图片 image ， 音频 audio等等）
//如果是图片消息最好能把宽高比加进去
- (void)sendMsgWithText:(NSString *)text
               bodyType:(NSString *)bodyType
             imageRatio:(CGFloat)ratio
{
    //发送数据
    XMPPMessage *msg = [XMPPMessage messageWithType:@"chat" to:self.friendJID];
    [msg addAttributeWithName:kBodyTypeKey stringValue:bodyType];
    [msg addAttributeWithName:kImgRatioKey floatValue:ratio];
    [msg addBody:text];
    [[XMPPManager sharedManager].xmppStream sendElement:msg];
}

/**
 *  发送图片：1、先上传图片到服务器2、拼接上传图片的连接 3、返回图片链接（上传的连接跟返回的连接一样的）4、在接收端（客户端下载并渲染）
 */

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
//    NSLog(@"%@",info);
    // 隐藏图片选择器的窗口
    [self dismissViewControllerAnimated:YES completion:nil];
    
    // 获取图片
    UIImage *image = info[UIImagePickerControllerOriginalImage];
    
    // 把图片发送到文件服务器
    //http post put
    /**
     * put实现文件上传没post那烦锁，而且比POST快
     * put的文件上传路径就是下载路径
     
     *文件上传路径 http://localhost:8080/imfileserver/Upload/Image/ + "图片名【程序员自已定义】"
     */
    
    // 1.取文件名 用户名 + 时间(201412111537)年月日时分秒
    NSString *user = [UserLocalInfo sharedUserInfo].userId;
    NSDateFormatter *dataFormatter = [[NSDateFormatter alloc] init];
    dataFormatter.dateFormat = @"yyyyMMddHHmmss";
    NSString *timeStr = [dataFormatter stringFromDate:[NSDate date]];
    
    // 针对我的服务，文件名不用加后缀
    NSString *fileName = [user stringByAppendingString:timeStr];
    // 2.拼接上传路径
    NSString *uploadUrl = [@"http://localhost:80/Mytest/Upload/Image/" stringByAppendingFormat:@"%@.jpg",fileName];
    
    // 3.使用HTTP put 上传
//#warning 图片上传请使用jpg格式 因为我写的服务器只接接收jpg
    [self.httpTool uploadData:UIImageJPEGRepresentation(image, 0.75) url:[NSURL URLWithString:uploadUrl] progressBlock:nil completion:^(NSError *error) {
        if (!error) {
            SLog(@"上传成功");
            // 图片发送成功，把图片的URL传Openfire的服务
            [self sendMsgWithText:uploadUrl bodyType:@"image" imageRatio:0];
        }
    }];
}

//造的图片假数据
- (NSDictionary *)getImgPathWithRandom:(NSInteger)index {
    
    NSArray<NSDictionary *> *array = @[@{@"imagePath" : @"https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3691141671,1410525831&fm=11&gp=0.jpg", kImgRatioKey:@(0.64)},
                       @{@"imagePath" : @"https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3691141671,1410525831&fm=11&gp=0.jpg", kImgRatioKey:@(0.664)},
                       @{@"imagePath" : @"https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2875807705,1383536284&fm=11&gp=0.jpg", kImgRatioKey:@(1.51)},
                       @{@"imagePath" : @"https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=326641642,2508964098&fm=11&gp=0.jpg", kImgRatioKey:@(0.875)},
                       @{@"imagePath" : @"https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2397261455,2165388321&fm=27&gp=0.jpg", kImgRatioKey:@(0.75)},
                       @{@"imagePath" : @"https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=563059728,1679203846&fm=27&gp=0.jpg", kImgRatioKey:@(0.824)},
                       @{@"imagePath" : @"https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1647217437,1004096978&fm=27&gp=0.jpg", kImgRatioKey:@(1.453)}
                       ];
    return array[index];
}

//假的视频数据
- (NSString *)getVideoURLString:(NSInteger)index {
    NSArray *videoUrl = @[@"http://pic.ibaotu.com/00/21/56/75n888piCX95.mp4",@"http://pic.ibaotu.com/00/21/32/86a888piCWij.mp4",@""];
    return videoUrl[index];
}

@end
